﻿using System;
using System.Globalization;
using System.IO;
using Microsoft.WowAddonStudio.FrameXml.Formats.Mpq;
using Microsoft.WowAddonStudio.FrameXml.Services;
using Microsoft.WowAddonStudio.Services;
using System.Diagnostics;

namespace Microsoft.WowAddonStudio.FrameXml.Editor.Support
{
	/// <summary>
	/// Creates initialized ResourceFileLoader instances.
	/// </summary>
	public static class ResourceFileLoaderFactory
	{
		private const string mpqFolderRelativePath = "Data";

		/// <summary>
		/// Creates the resource file loader.
		/// </summary>
		/// <param name="provider">The provider.</param>
		/// <returns>The initialized ResourceFileLoader instance.</returns>
		public static ResourceFileLoader CreateResourceFileLoader(IServiceProvider provider)
		{
			if (provider == null)
				throw new ArgumentNullException("provider");

            // Create resource file loader instance
            var resourceFileLoader = new ResourceFileLoader();

            // Get WoW locator service and see if a WoW installation was detected
			var wowLocatorService = (IWowLocatorService)provider.GetService(typeof(IWowLocatorService));
            if (wowLocatorService != null && wowLocatorService.IsWowInstalled)
            {

                // Get WoW base path    
                string wowBasePath = wowLocatorService.GetWowBasePath();

                // Add WoW base path to resource file loader
                resourceFileLoader.BasePaths.Add(wowBasePath);

                // Combine MPQ folder path
                string mpqFolderPath = Path.Combine(wowBasePath, mpqFolderRelativePath);

                try
                {
                    // Find the installed locale folder under the MPQ folder
                    string[] mpqDirectories = Directory.GetDirectories(mpqFolderPath);

                    // Make sure the directory is available
                    if (mpqDirectories.Length > 0)
                    {
                        // Use the first directory
                        string localeDirectory = mpqDirectories[0];
                        string locale = localeDirectory.Substring(localeDirectory.LastIndexOf(Path.DirectorySeparatorChar) + 1);

                        // Look up patch MPQs
                        var patchMpqPathFilter = String.Format(CultureInfo.InvariantCulture, "patch-{0}*.MPQ", locale);
                        var patchMpqs = Directory.GetFiles(localeDirectory, patchMpqPathFilter);

                        // Sort and revers the patch MPQs
                        Array.Sort(patchMpqs);
                        Array.Reverse(patchMpqs);

                        // Add patch MPQs to resource file loader in reverse order
                        foreach (var patchMpq in patchMpqs)
                        {
                            // Construct path to patch MPQ archive
                            string patchMpqArchivePath = Path.Combine(localeDirectory, patchMpq);

                            // Validate patch MPQ and add it to resource file loader
                            if (MpqArchive.IsValidMpqArchive(patchMpqArchivePath))
                                resourceFileLoader.MpqArchives.Add(new MpqArchive(patchMpqArchivePath));
                        }

                        // Construct path to locale-specific MPQ archive
                        string mpqArchivePath = Path.Combine(localeDirectory, String.Format("locale-{0}.MPQ", Path.GetFileName(localeDirectory)));

                        // Validate locale-specific MPQ and add it to resource file loader
                        if (MpqArchive.IsValidMpqArchive(mpqArchivePath))
                            resourceFileLoader.MpqArchives.Add(new MpqArchive(mpqArchivePath));
                    }
                }
                catch (Exception exception)
                {
                    Trace.WriteLine(exception.Message);
                }
            }

		    return resourceFileLoader;
		}

		/// <summary>
		/// Creates the resource file loader.
		/// </summary>
		/// <returns></returns>
		public static ResourceFileLoader CreateResourceFileLoader()
		{
			return new ResourceFileLoader();
		}
	}
}